# -*- coding: utf-8 -*-
import utils
import re
import random
import json
import requests
import threading
from login import Lighthouse, use_default_login
from urllib3.exceptions import InsecureRequestWarning

# 禁用安全请求警告
requests.urllib3.disable_warnings(InsecureRequestWarning)


class WeChatClient:
    def __init__(self, login_service, url='https://mp.weixin.qq.com'):
        """
        通过灯塔登录接口获取公众号后台资料
        :param Lighthouse login_service:
        """
        self.url = url
        self.login = login_service
        self.session = utils.requests_retry_session()
        self.gh_id = None
        self.gh_nickname = None
        self.token = None
        self.index_url = None
        self.index_response = None
        self.violation_list = []

    def log_line(self, msg, gh_nickname=None, gh_id=None):
        line = '[{}]({}) {}'.format(gh_nickname if gh_nickname else self.gh_nickname,
                                    gh_id if gh_id else self.gh_id, msg)
        print(line)
        return line

    def log_err(self, err, logtype='log', gh_nickname=None, gh_id=None):
        utils.log_error(self.log_line(err, gh_nickname, gh_id), logtype)

    def debug_log(self, err, logtype='debug', gh_nickname=None, gh_id=None):
        utils.log_error(self.log_line(err, gh_nickname, gh_id), logtype)
        print(err)

    def detect_account_type(self):
        m = re.search(r'>((订阅|服务)号)</a>', self.index_response, re.MULTILINE)
        if m:
            return m.group(1)

    def enter(self, gh_id, gh_nickname):
        cookies = self.login.get_wx_cookie(gh_id)
        if cookies:
            self.log_line('获取Cookie成功', gh_nickname, gh_id)
            utils.set_cookies(self.session, cookies)
        else:
            self.log_line('一键登录状态异常', gh_nickname=gh_nickname, gh_id=gh_id)
            infos = {
                "nickname": gh_nickname,
                "Id": gh_id,
                "all_reading": "一键登录异常",
                "date_time": ""
            }
            with open("graphic_reader_info.json", "a", encoding="utf-8") as f:
                f.write(json.dumps(infos) + "\r")
            return False
        try:
            response = self.session.get(url=self.url, verify=False)
            self.index_url = str(response.url)
            try:
                token = re.findall('token=(\\d+)', self.index_url)[0]
            except IndexError:
                self.log_err('微信后台登录失败，检查Cookie是否有效', gh_nickname=gh_nickname, gh_id=gh_id)
                return False
            self.gh_id = gh_id
            self.gh_nickname = gh_nickname
            self.token = token
            self.index_response = response.content.decode('utf-8')
            self.log_line('后台登录成功，Token={}'.format(token))
            return True
        except Exception as e:
            print(e)
            return False

    def save_data(self, data_file, data_date, data):
        with utils.open_write_data_file(self.gh_id, data_file, data_date) as f:
            json.dump(data, f)

    def detect_or_save(self, data_file, data_name, data_date, func, skip_exist=True, verbose=True):
        if skip_exist and utils.has_data_file(self.gh_id, data_file, data_date):
            if verbose:
                self.log_line('已存在{}，跳过'.format(data_name))
        else:
            if verbose:
                self.log_line('开始获取{}'.format(data_name))
            data = func(data_date)
            if data:
                if verbose:
                    self.log_line('获取{}成功'.format(data_name))
                self.save_data(data_file, data_date, data)
            else:
                self.log_err('获取{}失败,请重试,或单独爬取'.format(data_name))

    def save_basic_info(self, account, date):
        self.save_data('basic.json', date, account)

    def save_graphic_reading(self, date, nickname):
        resp = self.session.get(
            '{0}/misc/appmsganalysis?action=report&type=daily&begin_date={1}&end_date={1}&token={2}'
            '&lang=zh_CN&f=json&ajax=1&random={3}'.format(self.url, date, self.token, random.random()), verify=False)
        try:
            data = resp.json()
            all_reading = ''
            date_time = ''
            if len(data["item"]) != 0:
                for info in data["item"]:
                    if info["user_source"] == 99999999:
                        all_reading = info["int_page_read_count"]
                        date_time = info["ref_date"]
            infos = {
                "nickname": nickname,
                "Id": self.gh_id,
                "all_reading": all_reading,
                "date_time": date_time
            }
            with open("graphic_reader_info.json", "a", encoding="utf-8") as f:
                f.write(json.dumps(infos) + "\r")
        except (KeyError, ValueError, TypeError):
            self.debug_log(resp.content)

    def get_nickname_when_not(self):
        resp = self.session.get(
            '{0}/cgi-bin/settingpage?t=setting/index&action=index&token={1}&lang=zh_CN&f=json&ajax=1&random={2}'
            .format(self.url, self.token, random.random()))
        nickname = ''
        wx_id = ''
        gs = ''
        try:
            data = resp.json()
            nickname = data['setting_info']['nickname']['nickname']
            wx_id = data['setting_info']['username']
            gs = data['setting_info']['contractor_info']['name']
        except:
            self.debug_log(resp.content)
        return nickname, wx_id, gs


class Threading_thread(threading.Thread):
    def __init__(self, login_service, account, data_date=None):
        threading.Thread.__init__(self)
        self.login_service = login_service
        self.account = account
        self.data_date = data_date

    def run(self):
        if not self.data_date:
            self.data_date = utils.get_yesterday()
        srv = WeChatClient(self.login_service)
        if not srv.enter(self.account['gh_id'], self.account['nickname']):
            return
        account_type = srv.detect_account_type()
        if account_type:
            srv.log_line(account_type)
            self.account['type'] = account_type
        self.account['nickname'], self.account['wx_id'], self.account['gs'] = srv.get_nickname_when_not()
        srv.save_basic_info(self.account, self.data_date)
        srv.save_graphic_reading(self.data_date, self.account["nickname"])


def test_collect(thread=8):
    library = utils.default_library()
    account_chunks = library.get_account_chunks(thread)
    login_srv = use_default_login()
    pool = []
    for gh_id_list in account_chunks:
        for gh_id in gh_id_list:
            account = library.get_account_data(gh_id)
            thread = Threading_thread(login_srv, account)
            thread.start()
            pool.append(thread)
        for thread in pool:
            thread.join()
